/*
 * @Author: 黑白灰01 3193273703@qq.com
 * @Date: 2025-08-29 18:00:27
 * @LastEditors: 黑白灰01 3193273703@qq.com
 * @LastEditTime: 2025-09-01 16:18:52
 * @FilePath: /hei-oa/src/user/user.service.ts
 * @Description: 用户服务
 */
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { User } from './entities/user.entity';
import { FindOptionsWhere, Like, Repository } from 'typeorm';
import { EncryptService } from 'src/utils/encrypt.service';
import { PaginationDto } from 'src/common/dto/pagination.dto';
import { PaginationResponseDto } from 'src/common/dto/pagination-response.dto';
import { plainToClass } from 'class-transformer';
import { UserVo } from './dto/user.vo';
import { NotFoundException } from '@nestjs/common/exceptions';

@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User)
    private usersRepository: Repository<User>,
    private encryptService: EncryptService,
  ) {}

  /**
   * @description: 用户添加
   * @param {CreateUserDto} createUserDto
   * @return {Promise<UserVo>} 脱敏后的用户信息
   */
  async create(createUserDto: CreateUserDto): Promise<UserVo> {
    const user = new User();
    Object.assign(user, createUserDto);
    
    // 设置默认密码并加密
    user.password = await this.encryptService.encrypt('12345678');
    user.lastLoginTime = new Date();
    
    const savedUser = await this.usersRepository.save(user);
    return this.sanitizeUser(savedUser);
  }
  
  /**
   * @description: 用户列表（分页）
   * @param {PaginationDto} paginationDto
   * @return {Promise<PaginationResponseDto<UserVo>>} 脱敏后的用户分页列表
   */
  async paginate(
    paginationDto: PaginationDto,
  ): Promise<PaginationResponseDto<UserVo>> {
    const { page, pageSize, keyword, sortBy, sortDirection } = paginationDto;

    // 处理搜索条件 - 创建 OR 条件数组
    const where: FindOptionsWhere<User>[] = [];
    
    if (keyword) {
      // 使用OR条件搜索多个字段
      where.push({ username: Like(`%${keyword}%`) });
      where.push({ email: Like(`%${keyword}%`) });
      where.push({ fullName: Like(`%${keyword}%`) });
      where.push({ phone: Like(`%${keyword}%`) });
    }

    // 使用findAndCount查询
    const [items, total] = await this.usersRepository.findAndCount({
      where: where.length > 0 ? where : undefined, // 使用undefined而不是空对象
      skip: (page - 1) * pageSize,
      take: pageSize,
    });

    // 修复第78行附近的代码如下：
const sanitizedItems = await Promise.all(
  items.map(user => this.sanitizeUser(user))
);

return new PaginationResponseDto(sanitizedItems, total, paginationDto);


  }
  
  /**
   * @description: 用户详情
   * @param {number} id
   * @return {Promise<UserVo | null>} 脱敏后的用户信息
   */
  async findOne(id: number): Promise<UserVo | null> {
    const user = await this.usersRepository.findOneBy({ id });
    if (!user) return null;
    return this.sanitizeUser(user);
  }

  /**
   * @description: 用户更新
   * @param {number} id
   * @param {UpdateUserDto} updateUserDto
   * @return {Promise<UserVo>} 脱敏后的更新用户信息
   */
  async update(id: number, updateUserDto: UpdateUserDto): Promise<UserVo> {
    const existingUser = await this.usersRepository.findOneBy({ id });
    
    if (!existingUser) {
      throw new NotFoundException('用户不存在');
    }
    
    // 更新用户字段
    Object.assign(existingUser, updateUserDto);
    
    // 如果更新密码，需要加密
    if (updateUserDto.password) {
      existingUser.password = await this.encryptService.encrypt(updateUserDto.password);
    }

    const updatedUser = await this.usersRepository.save(existingUser);
    return this.sanitizeUser(updatedUser);
  }
  
  /**
   * @description: 用户删除
   * @param {number} id
   * @return {Promise<void>}
   */
  async remove(id: number): Promise<void> {
    const result = await this.usersRepository.delete(id);
    
    if (result.affected === 0) {
      throw new NotFoundException(`用户ID ${id} 不存在`);
    }
  }
  
  /**
   * @description: 用户数据脱敏方法
   * @param {User} user 原始用户实体
   * @return {UserVo} 脱敏后的用户视图对象
   */
  private async sanitizeUser(user: User): Promise<UserVo> {
    const userVo = new UserVo();
    Object.assign(userVo, user);
    // 可在此处添加额外的脱敏逻辑，例如删除 password 字段等
    delete (userVo as any).password;
    return userVo;
  }
}